<template>
  <view class="stack-carousel" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd">
    <view class="stack-list">
      <view
        v-for="(item, idx) in list"
        :key="idx"
        class="stack-item"
        :class="{ active: idx === current }"
        :style="getStyle(idx)"
        @click="onClickImg(item)">
        <image :src="item.memberAvatar || 'https://cdn.xmxiaomai.com/isong_static/music/music-default-avatar.png'" mode="aspectFill" />
      </view>
    </view>
  </view>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue';
import type { Index } from '@/api/data';

const props = defineProps({
  list: {
    type: Array as () => Index.MemberRecommend.Data[],
    default: () => [],
  },
});
const current = ref(2); // 默认中间
const emit = defineEmits(['click']);
// 自动轮播
let timer: any = null;
const startAutoPlay = () => {
  timer = setInterval(() => {
    current.value = (current.value + 1) % props.list.length;
  }, 300000);
};
const stopAutoPlay = () => {
  if (timer) clearInterval(timer);
};
const onClickImg = (item: Index.MemberRecommend.Data) => {
  emit('click', item);
};
onMounted(() => {
  startAutoPlay();
});
onBeforeUnmount(() => {
  stopAutoPlay();
});

// 手势滑动
let startX = 0;
let moveX = 0;
const onTouchStart = e => {
  stopAutoPlay();
  startX = e.touches[0].clientX;
};
const onTouchMove = e => {
  moveX = e.touches[0].clientX;
};
const onTouchEnd = () => {
  const deltaX = moveX - startX;
  if (Math.abs(deltaX) > 40) {
    if (deltaX < 0) {
      // 向左滑
      current.value = (current.value + 1) % props.list.length;
    } else {
      // 向右滑
      current.value = (current.value - 1 + props.list.length) % props.list.length;
    }
  }
  startAutoPlay();
  // 重置
  startX = 0;
  moveX = 0;
};

// 堆叠样式
const getStyle = idx => {
  const offset = idx - current.value;
  const len = props.list.length;
  // 支持循环
  let realOffset = offset;
  if (offset > len / 2) realOffset = offset - len;
  if (offset < -len / 2) realOffset = offset + len;
  const absOffset = Math.abs(realOffset);
  if (absOffset > 2) return { display: 'none' };
  const scale = 1 - absOffset * 0.1;
  const opacity = 1 - absOffset * 0.3;
  const zIndex = 10 - absOffset;
  const translateX = realOffset * 151;
  const translateY = absOffset * 60;
  return {
    transform: `translateX(${translateX}rpx) translateY(${translateY}rpx) scale(${scale})`,
    opacity,
    zIndex,
  };
};
</script>
<style lang="scss" scoped>
.stack-carousel {
  width: 100%;
  height: 320rpx;
  display: flex;
  justify-content: center;
  align-items: center;
  .stack-list {
    position: relative;
    width: 100%;
    height: 320rpx;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .stack-item {
    position: absolute;
    width: 240rpx;
    height: 240rpx;
    border-radius: 20rpx;
    overflow: hidden;
    box-shadow: 0rpx 2rpx 20rpx 0rpx rgba(67, 2, 2, 0.75);
    border: 3rpx solid #ffd700;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    image {
      width: 100%;
      height: 100%;
      display: block;
    }
  }
  .stack-item.active {
    border: 4rpx solid #fff;
    box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.25);
  }
}
</style>
